/**
 * 将webpack中生产环境(production)和开发环境(development)
 * 公用的模块导入到common中以便复用
 * webpcak 是使用CommonJs的语法规范
 * webpack中四大模块
 * 1. entry (入口)
 * 2. module (模块规则)
 * 3. plugins (插件)
 * 4. output (出口)
*/

/**
 * path 是用于处理相关的路径
 * process.env.NODE_ENV 是用于判断是production还是development
 * HtmlWebpackPlugin 是用于处理html文件处理的相关模块
 * MiniCssExtractPlugin 是用于将css代码拆离html
*/
const path = require('path')
const webpack = require('webpack')
const HtmlWebpackPlugin = require('html-webpack-plugin')
const MiniCssExtractPlugin = require('mini-css-extract-plugin')

/**
 * 下面插件是用于性能优化处理
 * WebpackBundleAnalyzer 是用于分析打包后代码的体积大小
 * HappyPack 允许进行多线程的任务
*/
// const WebpackBundleAnalyzer = require('webpack-bundle-analyzer')
// const { BundleAnalyzerPlugin } = WebpackBundleAnalyzer
const HappyPack = require('happypack')

// function resolve (arg) {
//   return path.resolve(__disname, '../', arg)
// }

module.exports = {
  entry: {
    // bundle 是指的是打包后的名称
    // 使用__dirname 需要使用path模块，表示当前父级目录，path路径最好使用绝对路径
    bundle: path.resolve(__dirname, '../src/main.js')
    // chunk: ['react']
  },

  output: {
    // 出口需要两个条件
    // filename: 打包好的文件名，由于文件可能多次打包，所以文件名需要加入哈希值，以便每次文件打包后，能及时更新到浏览器，更新强缓存
    // path: 打包好的文件存放的位置，打包完成后的文件，一般是存放在dist文件下
    // 使用clear选项，每次重新打包的文件都会被删除，再次打包
    filename: '[name].[chunkhash].js',
    path: path.resolve(__dirname, '../dist'),

    // Webpack（5.20.0+）的写法，用于自动清除 dist 目录
    clean: true,
    chunkFilename: '[name].[chunkhash].js'
  },

  module: {
    // 在rules数组中配置相应的规则，可以解析对应的js、css、scss、less、img
    // plugins只是为了补充rules规则无法解析具体的小规则
    // test表示对应的规则，use是表示使用什么模块
    
    rules: [
      // 当Webpack进行编译打包时，如果检测到文件模块是以.js后缀结尾的，我就使用babel-loader进行加载
			// 进一步使用 @babel/core, @babel/preset-env 进行编译、转译
      {
        test: /\.(js|jsx)$/,
        // use: ['babel-loader'], // 不使用缓存的写法
        use: [
          {
            loader: 'happypack/loader',
            // 对babel-loader进行缓存，第二次就能开启缓存
            options: {
              cacheDirectory: true
            },
          }
        ],
        exclude: /node_modules/
      },

      /**
       * scss定义规则
       * 1. sass-loader 用于加载scss文件，交给sass编译器去处理
       * 2. sass 编译器会把scss文件编译成为css文件
       * 3. css-loader 加载css、style-loader 把css加入到DOM树中
       * 4. 在使用多个loader时，先起作用的loader在最后面
       * 5. MiniCssExtractPlugin.loader作用是把css代码抽离出来，放在独立的css文件中
      */
      {
        test: /\.(css|scss)$/,
        use: [MiniCssExtractPlugin.loader, 'css-loader', 'sass-loader']
      },

      {
        test: /\.less$/,
        use: [
          'style-loader',
          'css-loader',
          {
            loader: 'less-loader',
            options: {
              lessOptions: {
                modifyVars: {
                  'primary-color': '#1DA57A',
                  'link-color': '#1DA57A',
                  'border-radius-base': '2px',
                },
                javascriptEnabled: true,
              }
            }
          }
        ]
      },

      // file-loader的作用，用于文件、图片等，返回文件图片的路径
      {
        test: /\.(png|jpg|jpeg|gif|svg)$/,
        type: 'assets/resource'
      },

      // 自定义loaders来处理.txt文件
      {
        test: /\.txt$/,
        use: [
          {
            loader: path.resolve(__dirname, './custom-loader.js')
          }
        ]
      }
    ]
  },

  plugins: [
    // 作用：用于把打包后的js文件自动插入到index.html中
    new HtmlWebpackPlugin({
			template: path.resolve(__dirname, '../public/index.html'),
			title: 'Hello',
			filename: 'index.html',
			minify: false
		}),

    // 把.js文件中import的样式文件抽离出来
		new MiniCssExtractPlugin({
      attributes: {
        id: 'target',
        'data-target': 'example',
      },
			filename: '[name].[chunkhash].css'
    }),

		// 在控制台上显示编译进度
		new webpack.ProgressPlugin(),

		/* // 一个很好用的打包分析工具
		new BundleAnalyzerPlugin({
			analyzerPort: 8888,
			openAnalyzer: true
		}), */

		// 开启多线程babel编译构建
		new HappyPack({
    	loaders: [ 'babel-loader' ],
			threads: 3
  	})
  ],

  resolve: {
    // 创建别名，将使用@符号指向到src
    alias: {
      '@': path.resolve(__dirname, '../src'),
      extensions: ['.js', '.jsx', '.ts', '.json', '.vue']
    }
  }
}